package com.xnyzc.lhy.common.component.config.security;

import com.alibaba.druid.util.StringUtils;
import com.google.common.collect.Lists;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.ELoginUserType;
import com.xnyzc.lhy.common.penum.ERole;
import com.xnyzc.lhy.common.penum.EStatus;
import com.xnyzc.lhy.common.penum.EYn;
import com.xnyzc.lhy.common.penum.user.UserIdEnum;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.EmptyUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;

/**
 * @Description:
 * @Author: scootXin
 * @Date: 2018/12/20 18:19
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "Token 用户信息", description = "Token 用户信息")
public class TokenUser<T> implements Serializable, UserDetails {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "用户实体")
    private T user;

    @ApiModelProperty(value = "用户ID")
    private Long TokenUserId;

    @ApiModelProperty(value = "角色列表")
    private List<Long> roles;

    @ApiModelProperty(value = "权限列表")
    private List<String> permissions;

    @ApiModelProperty(value = "用户登陆类型")
    private ELoginUserType loginUserType;

    @ApiModelProperty(value = "客户端id")
    private String clientId;

    @ApiModelProperty(value = "数据范围")
    private List<String> dataScope;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        if (permissions == null && roles == null) {
            return Lists.newArrayList();
        }

        List<SimpleGrantedAuthority> list = Lists.newLinkedList();
        if(!permissions.isEmpty()){
            for (String permission : permissions) {
                list.add(new SimpleGrantedAuthority(permission));
            }
        }
        for (Long role : roles) {
            list.add(new SimpleGrantedAuthority("ROLE_" + role));
        }

        return list;
    }

    /**
     * 是否为平台管理员
     *
     * @return
     */
    public boolean isPlatformManager() {
        return roles == null ? false : roles.contains(ERole.manager.getValue());
    }


    /**
     * 是否管理员
     */
    public boolean isFm() {
        return roles == null ? false : roles.contains(ERole.fm.getValue());
    }

    /**
     * 是否为乘客
     *
     * @return
     */
    public boolean isCustomer() {
        return roles == null ? false : roles.contains(ERole.c.getValue());
    }

    /**
     * 是否为司机
     *
     * @return
     */
    public boolean isDriver() {
        return roles == null ? false : roles.contains(ERole.d.getValue());
    }

    /**
     * 获取userId
     *
     * @return
     */
    public long getUserId() {
        try {
            Class<?> aClass = user.getClass();
            Field[] declaredFields = aClass.getDeclaredFields();
            if (EmptyUtil.isEmpty(declaredFields)) {
                throw PangException.create(EErrorCode.userFieldError);
            }
            String fieldName = null;
            loop:
            for (Field field : declaredFields) {
                fieldName = field.getName();
                for (UserIdEnum userIdEnum : UserIdEnum.values()) {
                    if (StringUtils.equals(fieldName, userIdEnum.getLoginMsg())) {
                        break loop;
                    }
                }
                fieldName = null;
            }
            if (EmptyUtil.isEmpty(fieldName)) {
                throw PangException.create(EErrorCode.authDenied, "您不具备访问此系统的权限");
            }
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Method getMethod = aClass.getMethod(getMethodName, new Class[]{});
            Long result = (Long) getMethod.invoke(user, new Object[]{});
            this.TokenUserId = result;
            return result;
        } catch (Exception e) {
            throw PangException.create(EErrorCode.userFieldError, "获取用户信息异常");
        }
    }

    /**
     * 获取token的唯一标识
     *
     * @return
     */
    public String getTokenIndex() {
        if (CheckUtil.objIsEmpty(TokenUserId)) {
            return getTokenUserId() + ":" + getClientId();
        }
        return this.TokenUserId + ":" + getClientId();
    }

    @Override
    public String getPassword() {
        return null;
    }

    @Override
    public String getUsername() {
        return null;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return !EYn.isYes(1);
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return EStatus.normal.equals("normal") && isAccountNonExpired() && isAccountNonLocked();
    }

}
